Add support for Microsoft.WindowsAppSDK.Foundation bootstrapper#30
Add support for Microsoft.WindowsAppSDK.Foundation bootstrapper#30
Conversation
There was a problem hiding this comment.
Pull request overview
Adds CMake overlay support for the Microsoft.WindowsAppSDK.Foundation NuGet package’s “framework bootstrapper” scenario by introducing new convenience targets and conditionally exposing a bootstrap target when Microsoft.WindowsAppSDK.Runtime is available.
Changes:
- Adds
Microsoft.WindowsAppSDK.Foundation_Frameworkas an INTERFACE convenience target. - Conditionally defines
Microsoft.WindowsAppSDK.Foundation_FrameworkBootstrapwhenMicrosoft.WindowsAppSDK.Runtimecan be found, wiring in bootstrapper sources/defines and linking to the bootstrap DLL/implib. - Leaves existing
..._SelfContainedbehavior intact.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
overlay/microsoft.windowsappsdk.foundation/microsoft.windowsappsdk.foundation-config.cmake
Outdated
Show resolved
Hide resolved
overlay/microsoft.windowsappsdk.foundation/microsoft.windowsappsdk.foundation-config.cmake
Show resolved
Hide resolved
jonwis
left a comment
There was a problem hiding this comment.
Seems pretty reasonable. App "targets" the framework & bootstrapper. Is it an error to target _frameworkbootstrap without _framework ?
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
overlay/microsoft.windowsappsdk.foundation/microsoft.windowsappsdk.foundation-config.cmake
Outdated
Show resolved
Hide resolved
I think I have a proposal to comment (2) in the description that shakes out really quite nicely that means that _frameworkbootstrap would be an implementation detail. Let me write/code it up... Ah. I should answer your question, though. I think it's fine to reference _frameworkbootstrap without _framework - you could be in a simple 'hosting exe' that doesn't need the winmd projections, but wants package-graph updates for DLL's that you LoadLibrary. But since the _framework target is really just setting include paths I don't think there's a concern to superset them. |
bbc2970 to
71ecfbb
Compare
overlay/microsoft.windowsappsdk.foundation/microsoft.windowsappsdk.foundation-config.cmake
Show resolved
Hide resolved
overlay/microsoft.windowsappsdk.foundation/microsoft.windowsappsdk.foundation-config.cmake
Outdated
Show resolved
Hide resolved
overlay/microsoft.windowsappsdk.foundation/microsoft.windowsappsdk.foundation-config.cmake
Outdated
Show resolved
Hide resolved
overlay/microsoft.windowsappsdk.foundation/microsoft.windowsappsdk.foundation-config.cmake
Show resolved
Hide resolved
71ecfbb to
32ecaa3
Compare
32ecaa3 to
0fdee42
Compare
overlay/microsoft.windowsappsdk.foundation/microsoft.windowsappsdk.foundation-config.cmake
Outdated
Show resolved
Hide resolved
overlay/microsoft.windowsappsdk.foundation/microsoft.windowsappsdk.foundation-config.cmake
Outdated
Show resolved
Hide resolved
overlay/microsoft.windowsappsdk.foundation/microsoft.windowsappsdk.foundation-config.cmake
Outdated
Show resolved
Hide resolved
0fdee42 to
c395bce
Compare
The
Microsoft.WindowsAppSDK.FoundationNuGet package contains MSBuild/headers/source code/libs/dlls for 'bootstrapping' aspects of the Windows App SDK. This PR is to have a discussion as to how the support is surfaced.A couple of points to discuss:
There's a little awkwardness around
Microsoft.WindowsAppSDK.Runtime. TheMicrosoft.WindowsAppSDK.FoundationNuGet doesn't depend on theMicrosoft.WindowsAppSDK.RuntimeNuGet, but the bootstrapper code needs theWindowsAppSDK-VersionInfo.hfrom theMicrosoft.WindowsAppSDK.RuntimeNuGet. As a result, the CMake logic here checks to see if theMicrosoft.WindowsAppSDK.RuntimeCMake package is available, and only if it is, creates theMicrosoft.WindowsAppSDK.Foundation_FrameworkBootstraptarget. I couldn't find analogous logic in the MSBuild scripts, so I'm not really sure how it's handled.This PR specifically adds support for the
WindowsAppSdkBootstrapInitialize- andWindowsAppSdkDeploymentManagerInitialize- controlled bootstraps. In order to be able to accommodate multiple targets in a CMake build consumingMicrosoft.WindowsAppSDK.Foundation_Frameworkwith different configurations, I'm introducing generator-expression (documentation) logic to theMicrosoft.WindowsAppSDK.Foundation_Frameworktarget, so that consumers can set properties on the target that control the functionality that the consuming target gets. This is a little complicated to implement, but yields - IMHO - a well encapsulated implementation, and is clean to consume. Basically, each option that affects the source/pre-processor defines that a consume can apply manifests as a different target. Then theMicrosoft.WindowsAppSDK.Foundation_Framework-target will depend on each of those targets only if the consuming target has properties set:WindowsAppSdkBootstrapInitializeproperty (named identically to the MSBuild property), then theMicrosoft.WindowsAppSDK.Foundation_Framework-target will add a dependency on theMicrosoft.WindowsAppSDK.Foundation_DynamicDependencyBootstraptarget.WindowsAppSdkDeploymentManagerInitializeproperty then theMicrosoft.WindowsAppSDK.Foundation_Framework-target will add a dependency on theMicrosoft.WindowsAppSDK.Foundation_DeploymentManagerBootstraptarget.This means that consumers don't have to manage multiple libraries, CMake builds aren't bound to CMake variables (which would only be evaluated on the first
find_package). The implementation - whilst a little verbose - is quite nicely encapsulated and 'correct'. Here's a diagram that attempts to explain the target-graph--- config: flowchart: defaultRenderer: elk --- graph TD Framework["Foundation_Framework"] Foundation["Foundation"] DynDepBoot["Foundation_DynamicDependencyBootstrap"] DeployBoot["Foundation_DeploymentManagerBootstrap"] Bootstrap["Foundation_Bootstrap"] Runtime["Microsoft.WindowsAppSDK.Runtime"] Framework --> Foundation Framework -.->|"WindowsAppSdkBootstrapInitialize"| DynDepBoot Framework -.->|"WindowsAppSdkDeploymentManagerInitialize"| DeployBoot DynDepBoot --> Bootstrap DeployBoot --> Bootstrap Bootstrap --> RuntimeConsumers would write code like:
I pushed a small self-contained buddy test here incase folks want to try things out. Note: this is based on the 'develop' branch, but this PR is for the 'main' branch.
I've validated with Ninja and Visual Studio 2022 generators. When both
WindowsAppSdkBootstrapInitializeandWindowsAppSdkDeploymentManagerInitializeare unset orFALSE, theMicrosoft.WindowsAppRuntime.Bootstrap.dllfile isn't copied alongside the .exe. If either isTRUE, the file is copied, and the corresponding code is compiled into the consumer.